package lcmpt;

import java.util.Collection;
import java.util.List;

import javax.swing.plaf.ListUI;

import org.marc4j.marc.DataField;
import org.marc4j.marc.Record;
import org.marc4j.marc.Subfield;
import org.marc4j.marc.VariableField;

import de.dnb.basics.applicationComponents.ListUtils;
import de.dnb.basics.applicationComponents.RangeCheckUtils;
import de.dnb.basics.applicationComponents.StringUtils;
import de.dnb.basics.filtering.FilterUtils;
import de.dnb.basics.filtering.IFunction;
import de.dnb.basics.utils.HTMLUtils;
import de.dnb.basics.utils.MarcUtils;

public class LCMPTMarcUtils {

	public static String getPreferredName(Record record) {
		DataField dataField =
				de.dnb.basics.utils.MarcUtils.getHeadingField(record);
		return getName(dataField);
	}

	public static String getName(DataField dataField) {
		Subfield subfield = dataField.getSubfield('a');
		return subfield.getData();
	}

	public static List<String> getOBB(Record record) {
		Collection<DataField> obbFields =
				de.dnb.basics.utils.MarcUtils.getOBBFields(record);
		IFunction<DataField, String> function =
				new IFunction<DataField, String>() {
					@Override
					public String apply(DataField x) {
						return getName(x);
					}
				};
		return FilterUtils.map(obbFields, function);
	}

	public static boolean hasOB(Record record) {
		return !getOBB(record).isEmpty();
	}

	public static final String htmlOpen = "\n<p style=\"text-align:left; "
			+ "margin-left:50px; margin-right:50px\">";
	public static final String htmlClose = "</p>";

	public static String getSourcesAsHTML(Record record) {
		Collection<DataField> sourceFields = MarcUtils.getSourceFields(record);
		if (sourceFields.isEmpty())
			return "";
		String sources = "<h2>Quellen:</h2>";
		for (DataField dataField : sourceFields) {
			sources += htmlOpen;
			Subfield source = dataField.getSubfield('a');
			if (source != null)
				sources += "<b>in:</b> " + source.getData();
			Subfield def = dataField.getSubfield('b');
			if (def != null) {
				String defS = def.getData();
				sources += "<br>" + "<b>als:</b> " + defS;
			}
			sources += htmlClose;
		}
		return sources;
	}

	public static String getSynonymsAsHTML(Record record) {
		Collection<DataField> synFields = MarcUtils.getSynonymFields(record);
		if (synFields.isEmpty())
			return "";
		String syns = "<h2>Synonyme:</h2>";
		for (DataField dataField : synFields) {
			syns += htmlOpen;
			syns += getName(dataField);
			syns += htmlClose;
		}
		return syns;
	}

	public static String getOBBAsHTML(Record record) {
		List<String> obb = getOBB(record);
		if (obb.isEmpty())
			return "";
		String syns = "<h2>Oberbegriffe:</h2>";
		for (String ob : obb) {
			syns += htmlOpen;
			syns += HTMLUtils.makeHtmlRef(ob, ob);
			syns += htmlClose;
		}
		return syns;
	}

	public static String getUBBAsHTML(Collection<String> ubb) {
		if (ubb.isEmpty())
			return "";
		String ubbStr = "<h2>Unterbegriffe:</h2>";
		ubbStr += htmlOpen;
		IFunction<String, String> makeHTMLRef =
				new IFunction<String, String>() {
					@Override
					public String apply(String x) {
						return HTMLUtils.makeHtmlRef(x, x);
					}
				};
		ubbStr +=
				StringUtils
						.concatenate(", ", FilterUtils.map(ubb, makeHTMLRef));
		ubbStr += htmlClose;
		return ubbStr;
	}

	public static String getExplanatoriesAsHTML(Record record) {
		Collection<DataField> explFields =
				MarcUtils.getPublicGeneralNoteFields(record);
		if (explFields.isEmpty())
			return "";
		String expls = "<h2>Erläuterungen:</h2>";
		for (DataField dataField : explFields) {
			expls += concatenateSubsContainingLinks(dataField);
		}
		return expls;
	}

	public static String concatenateSubsContainingLinks(DataField dataField) {
		String s = htmlOpen;
		List<Subfield> explList = dataField.getSubfields();
		for (Subfield subfield : explList) {
			String data = subfield.getData();
			if (subfield.getCode() != 'a')
				s += data + " ";
			else {
				s +=
						HTMLUtils.makeHtmlRef(data.replaceAll("[!\"#\\$%&'\\*\\+,\\"
								+ "-\\./:;<=>?@\\^_`~]", ""), data)
								+ " ";
			}
		}
		s += htmlClose;
		return s;
	}

	public static String getTracingNotesAsHTML(Record record) {
		Collection<DataField> variableFields =
				MarcUtils.getTracingNoteFields(record);
		if (variableFields.isEmpty())
			return "";
		String syns = "<h2>Verweisungsvermerke:</h2>";
		for (DataField dataField : variableFields) {
			syns += concatenateSubsContainingLinks(dataField);
		}
		return syns;
	}

	/**
	 * Formatiert Marc-Datensatz als HTML: '\n' wird zu break, Überschrift wird
	 * hinzugefügt.
	 * 
	 * @param record
	 *            nicht null
	 * @return html
	 */
	public static String getRecordAsHTML(final Record record) {
		RangeCheckUtils.assertReferenceParamNotNull("record", record);
		String r = record.toString();
		r = r.replace("\n", "<br>");
		return "<h3>Marc-Datensatz:</h3>" + htmlOpen + r + htmlClose;
	}

}
